<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>变量提升，与TDZ</title>
  </head>
  <body>
    <script>
      let a = 0;
      // let a =1;   变量已经声明过了，

      /*  console.log(a);
        for(let a =0;a<10;a++){
            console.log(a);
        } */

      /*  var names;
        console.log(names);
        只声明为赋值为undefined */

      /*  var name1='aa'
        console.log(name1);
        console.log(window.name1); 

        声明一个变量其实是在window对象时增加一个属性*/

      /*  let b = 'what'
        console.log(typeof b);
        b=13
        console.log(typeof b);
        b={}
        console.log(typeof b);
        
        使用typeof去判断数据类型*/

      /*   var c = '我是c'
        console.log(c);
        console.log(d);  // undefined    var 存在变量提升如果是let 会直接报 Uncaught ReferenceError（未捕获引用错误）
        var d = 'var存在变量提升'
        console.log(d);
 */

      // console.log(f);
      // let f =10;  // 初始化之前无法访问变量 let先声明在赋值

      /*  const test = '测试';
        console.log(test);
        let age = 18;
        console.log(age);
        // let和constant先声明后赋值
 */

      let num = 1;
      function funName() {
        num = 3;
        console.log(num);
      }

      funName();

      function mm(a = 1, b = a) {
        console.log(a);
      }
      mm();

      /* 
      TDZ
      TDZ 又称暂时性死区，指变量在作用域内已经存在，但必须在let/const声明后才可以使用。
      TDZ 可以让程序保持先声明后使用的习惯，让程序更稳定。    
      变量要先声明后使用
      建议使用 let/const 而少使用 var  
      */

      /* // 使用let/const 声明的变量在声明前存在临时性死区（TDZ）使用会发生错误

      console.log(x); // Cannot access 'x' before initialization
      let x = 1; */

      /*  // 在run函数作用域中产生 TDZ，不允许变量在未声明前使用。

      hd = "houdunren";
      function run() {
        console.log(hd);
        let hd = "hdcms";
      }
      run();
 */

      /* 
      // 下面代码 b 没有声明赋值不允许直接使用
      function hd(a = b, b = 3) {}
      hd(); //Cannot access 'b' before initialization */

      //  因为 a 已经赋值，所以 b 可以使用 a 变量，下面代码访问正常

      function hd(a = 2, b = a) {}
      hd();
    </script>
  </body>
</html>
